import itertools
import sys
import typing
import os


class BasicTool:
    @classmethod
    def contains_keywords(cls, target: str, key_words: tuple) -> bool:
        """
        判断target中是否包含key_words中的元素
        """
        for k in key_words:
            if k in target:
                return True
        return False

    @classmethod
    def is_empty_iter(cls, itera: typing.Iterator) -> typing.Tuple:
        """
        判断iterator是否为空，因为会改变原来的iterator，所以需要返回一个和原来iterator相同的iter
        """
        itera, peek = itertools.tee(itera)
        empty_flag = False
        try:
            next(peek)
        except StopIteration:
            empty_flag = True
        return iter, empty_flag

    @classmethod
    def find_abs_files(cls, root_path: str, file_filter=None) -> list:
        """
        返回目录下的所有文件的全路径
        """
        if sys.platform == "linux":
            meta_cmd = "find {} ! -name '.' -type f | sed 's/.//' | sed \"s:^:/:\""

            def f(x): return True if file_filter is None else file_filter

            output = os.popen(meta_cmd.format(root_path, root_path))
            print("linux platform: using find command to find files")
            return [x.strip() for x in output]
        subdir_list = [os.path.join(root_path, x) for x in os.listdir(root_path) if
                       os.path.isdir(os.path.join(root_path, x))]
        sub_list = list()
        for sd in subdir_list:
            sub_list.extend(cls.find_abs_files(
                os.path.join(root_path, sd), file_filter))
        direct_files = list()
        for file in os.listdir(root_path):
            fullpath = os.path.join(root_path, file)
            if os.path.isfile(fullpath):
                if file_filter is not None and not file_filter(file):
                    continue
                direct_files.append(fullpath)
        direct_files.extend(sub_list)
        return direct_files

    @classmethod
    def collect_files(cls, root_dir: str = os.getcwd(), delink=True, file_filter=None) -> set:
        """
        收集root_dir下的所有文件，包括所有子目录下的文件
        post_handler：在收集文件前进行后置处理
        delink：如果是链接，则收集真正的文件，而非链接文件
        return: 所有文件的base_name集合
        """
        base_filename_set = set()
        full_filename_set = cls.find_abs_files(root_dir, file_filter)
        for ff in full_filename_set:
            if delink and os.path.islink(ff):
                base_filename = os.readlink(ff)
            else:
                base_filename = ff.split("/")[-1]
            base_filename_set.add(base_filename)
        return base_filename_set


if __name__ == '__main__':
    file_list = BasicTool.find_abs_files(".")
    for x in file_list:
        print(x)
    print(len(file_list))
